/*
 * CS_PK_REQ_ROOM_JOIN.cpp
 *
 *  Created on: 2014. 1. 6.
 *      Author: the2
 */

#include "../../Command.h"
#include "../../engine.h"
#include "../../User.h"
#include "../../NLogic/Static.h"

namespace ProjectZ { namespace NCommand {

static void SendAckFail(User * pUser, int ack)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck	<< static_cast<int16_t>(ack);
	pAck->MakePacket(CMD_SC_PK_REQ_ROOM_JOIN);
	pUser->Send(pAck);
}

static void SendReqPKEnter(User *pUser, NLogic::Space * pBattleRoyal)
{
	int pos_x[4] = { 31*32, 42*32, 19*32, 10*32 };
	int pos_y[4] = { 13*32, 21*32, 27*32, 15*32 };
	int degree[4] = { 90, 180, 270, 0 };

	auto userTreeItr = pBattleRoyal->GetUserTree().begin();
	for ( int i = 0 ; userTreeItr != pBattleRoyal->GetUserTree().end() ; ++userTreeItr, i++ )
	{
		User * pOther = userTreeItr->second;
		pOther->Set_PK_Coordinate( pos_x[i], pos_y[i], degree[i] );
	}

	::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pNoti << static_cast<uint64_t>(pBattleRoyal->GetData()._index);
	pNoti->MakePacket(CMD_SC_REQ_PK_ENTER);
	pUser->GetSpace()->SendAll(pNoti);
	pUser->GetParty()->SetState(NLogic::Party::State::PK_ENTER_WAIT);
}

/*
// 배틀로얄 방입장요청
CS_PK_REQ_ROOM_JOIN	0x1422
{
	u32 u32room_number;	//입장할 방번호
}

SC_PK_REQ_ROOM_JOIN	0x1423
{
	s16  s16ack;

	u32 u32room_number;		//입장된 방번호
	u8  u8MaxMemeberCount;	//방인원 최대 수(배틀로얄은 4 혹은 3이 될 수 있음:우선은 3)
	u8  u8MemeberCount;		//현재 방에 인원 수
	{
		u32 gid;			//대기자 gid
	}
}
*/
void Command::CS_PK_REQ_ROOM_JOIN(User * pUser, ::Network::Packet * pPacket)
{
	NLogic::Space * pWorld = pUser->GetSpace();
	if (NULL == pWorld)
	{
		DEBUGLOG("%s NULL == pWorld", __FUNCTION__);
		SendAckFail(pUser, ACK_NO_SPACE);
		return;
	}

	if (pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD)
	{
		DEBUGLOG("%s pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD", __FUNCTION__);
		SendAckFail(pUser, ACK_NO_SPACE);
		return;
	}

	if (pUser->GetEnumState() != User::EnumState::__NONE__)
	{
		DEBUGLOG("%s pUser->GetEnumState() != User::EnumState::__NONE__", __FUNCTION__);
		SendAckFail(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	PREPARE_PACKET;

	uint32_t roomNumber = 0;

	* pPacket >> roomNumber;

	NLogic::Static::PKROOMTREE & pkRoomTree = NLogic::Static::Instance().GETPKROOMTREE();

	auto iter = pkRoomTree.find(roomNumber);
	if(pkRoomTree.end() == iter)
	{
		SendAckFail(pUser, ACK_PVP_PK_NOT_EXIST_ROOM);
		return;
	}

	NLogic::Party * pParty = iter->second->GetParty();
	if(NULL == pParty)
	{
		SendAckFail(pUser, ACK_PVP_PK_NOT_EXIST_ROOM);
		return;
	}

	if (pParty->GetState() != NLogic::Party::State::NEW_PK_ROOM_WAIT)
	{
		SendAckFail(pUser, ACK_PVP_PK_START_BATTLE);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	* pAck	<< static_cast<int16_t>(ACK_OK)
			<< static_cast<uint32_t>(iter->first)
			<< static_cast<uint8_t>(MAX_PK_INVITE);

	pUser->SetEnumState(User::EnumState::BATTLE_ROYAL_PARTY_WAIT);
	pParty->EnterUser(pUser);

	pWorld->LeaveUser(pUser);

	NLogic::Space * pBattleRoyal = iter->second;
	pBattleRoyal->EnterUser(pUser);

	pParty->AddAcceptUserTree(pUser);

	* pAck	<< static_cast<uint8_t>(pParty->GetAllUserTree().size());

	std::for_each(pParty->GetAllUserTree().begin(), pParty->GetAllUserTree().end(), [&](NLogic::Party::USERTREE::value_type & pair){
		* pAck << static_cast<uint32_t>(pair.second->GetUserSeq());
	});

	pAck->MakePacket(CMD_SC_PK_REQ_ROOM_JOIN);
	pUser->Send(pAck);

	::Network::Packet * pNoti = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pNoti << static_cast<uint32_t>(pUser->GetUserSeq());
	pNoti->MakePacket(CMD_SN_PK_REQ_ROOM_JOIN);
	pBattleRoyal->SendAllExceptMe(pNoti, pUser);


	if (pParty->GetAcceptUserTree().size() >= static_cast<size_t>(MAX_PK_INVITE))
	{
		SendReqPKEnter(pUser, pBattleRoyal);
	}
}

} /*NCommand*/ }  /*ProjectZ*/
